package com.grm.common.interceptor;

import com.grm.common.constant.SysConstant;
import com.grm.common.enums.ErrorEnum;
import com.grm.common.exception.BusinessException;
import com.grm.common.utils.JwtUtil;
import com.grm.common.utils.RedisUtil;
import com.grm.sys.constant.SysUserConstant;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.concurrent.TimeUnit;

/**
 * desc: 如果监听器、过滤器、 拦截器、 AOP都存在，则它们的执行顺序为：监听器 => 过滤器=> 拦截器=> AOP。
 * 接口进行token校验
 *
 * @author gaorimao
 * @since 2024/1/19 15:51
 */

@Component
@Slf4j
public class ApiInterceptor implements HandlerInterceptor {
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private RedisUtil redisUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();
        log.info("api interceptor uri = {}", requestURI);
        if (!requestURI.equals("/login")
                && !requestURI.equals("/logout")
                && !requestURI.equals("/captcha")
        ) {
            String header = request.getHeader(SysConstant.TOKEN);
            // 1、是否携带token
            if (StringUtils.isEmpty(header)) {
                throw new BusinessException(4011, "用户未登录！");
            }
            // 2、token合法性
            String username = jwtUtil.getUsername();
            // 3、token有效性
            String redisToken = redisUtil.get(String.format("token_%s", username));
            if (StringUtils.isEmpty(redisToken)) {
                throw new BusinessException(4012, "您长时间未操作，已退出登录，请重新登录，谢谢！");
            }
            // 4、token续签
            redisUtil.setExpire(String.format("token_%s", username), redisToken, 1L, TimeUnit.HOURS);
        }
        return true;
    }
}
